package Average;


import java.util.Date;

import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.wrapper.AgentContainer;
import jade.wrapper.AgentController;

import jess.*;


/**
 * *  Aceasta clasa este o clasa de laegatura pentru jess si agentul jade.
 * Din jess se apleaza cu parametrii de cerere a datelor.
 * Se creeaza agentul jade si se trimit parametrii pentru interogare.
 * Cand agentul a primit toate datele de la server, acesta va semnala aceast obiect si ii va transmite datele.
 * Datele se insereaza ca fapte in jess, care va calcula media valorilor. 
 *  Clasa implementeaza interfata pentru functie extinsa a jess 
 *  */
public class Average implements Userfunction {
	/**
	 *  numele clasei 
	 *  */
	public String getName(){
		return "Average";
	}
	/**
	 *  corpul functiei ce va fi executat la chemarea ei din jess 
	 *  4 parametri: primul este numele functiei apoi, cei 3 din jess (idul tabelei de date, data de start, data finala) 
	 *  */
	public Value call(ValueVector vv, Context context) {				
		try{
			/** 4 parametri: primul este numele functiei apoi, cei 3 din jess (idul tabelei de date, data de start, data finala) */
			if (vv.size() != 4)
				throw new JessException("Average",
				"Wrong number of arguments", vv.size()-1);
			else
			{
				/* scot valorile din argumentele primite */
				int id=vv.get(1).intValue(context);
				String date1=vv.get(1).stringValue(context);
				String date2=vv.get(2).stringValue(context);
				
				/* pegatesc valorile pentr a le trimite agentului */
				Object[] arguments = new Object[3];
				  arguments[0] = id;
				  arguments[1]=date1;
				  arguments[2]=date2;
				
				System.out.println("creez agent cu "+id+" "+date1+" "+date2);
			
				 /* obtin o referinta la instanta environmentului Jade activ */
				 jade.core.Runtime rt = jade.core.Runtime.instance();

			      /* setez sa se inchida containerul creeat cand se opreste aplicatia (obiectul instanta al acestei clase) */
			      rt.setCloseVM(true);

				  /* Se creeaza un proil pentru container, cel default */
				  Profile p = new ProfileImpl(false);

				  /* Creez un container diferit de cel principal 
				   * la aceeasi adresa si port */
			      System.out.println("Lansez containerul ..."+p);
				  AgentContainer ac = rt.createAgentContainer(p);

				  
				  /* variabila folosita pentru transmiterea argumentelor (contine si un avertisment cand datele sun gata) */
				  CondVar startUpLatch = new CondVar();
				  Object o[]=new Object[2];
				  o[0]=startUpLatch;
				  o[1]=arguments;
				  /* Creez agentul de tip AverageAgent cu argumentele creeate */
				  AgentController agent = ac.createNewAgent("AverageAgent", "Average.AverageAgent", o);

				  /* Si il porniesc */
				  System.out.println("Am pornit AverageAgent...");
				  agent.start();				  
						      
				  /* variabila pentru datele primite */
				  float[] values=null;
				  /* astept sa termine agentul de obtinut datele */
				  try {
					  values=startUpLatch.waitOn();
					  ac.kill();
				  }catch(InterruptedException ie) {
					  ie.printStackTrace();
				  }
				  
			System.out.println("back in Average");
			if(values!=null)
			{
				/* datele obtinute sunt introduse ca fapte in jess */
				for(int i=0;i<values.length;i++)
				{
					Fact f=new Fact("data",context.getEngine());
					f.setSlotValue("temp",new Value(values[i],RU.FLOAT));
					f.setSlotValue("date", new Value((new Date()).toString(),RU.STRING));
					System.out.println(values[i]);
					context.getEngine().assertFact(f);
					}
				}			
			}
			
		}catch(Exception e)
		{
			e.printStackTrace();
		}	
		return null;
		}

}
